package com.ajocer.springbootinit.config;

import io.github.resilience4j.circuitbreaker.CircuitBreaker;
import io.github.resilience4j.circuitbreaker.CircuitBreakerRegistry;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.time.Duration;

/**
 * 断路器配置类
 * 用于配置服务熔断功能，防止级联故障
 */
@Configuration
public class CircuitBreakerConfig {

    /**
     * 创建CircuitBreakerRegistry
     */
    @Bean
    public CircuitBreakerRegistry circuitBreakerRegistry() {
        return CircuitBreakerRegistry.ofDefaults();
    }

    /**
     * 创建默认断路器配置
     */
    @Bean
    public CircuitBreaker defaultCircuitBreaker(CircuitBreakerRegistry registry) {
        io.github.resilience4j.circuitbreaker.CircuitBreakerConfig config = io.github.resilience4j.circuitbreaker.CircuitBreakerConfig.custom()
                .failureRateThreshold(50)  // 失败率阈值，超过50%触发断路
                .slowCallRateThreshold(50) // 慢调用率阈值，超过50%触发断路
                .slowCallDurationThreshold(Duration.ofSeconds(1)) // 慢调用判定阈值
                .permittedNumberOfCallsInHalfOpenState(10) // 半开状态允许的调用次数
                .slidingWindowSize(100) // 滑动窗口大小
                .minimumNumberOfCalls(10) // 最小调用次数
                .waitDurationInOpenState(Duration.ofSeconds(10)) // 断路器打开状态持续时间
                .build();
        
        return registry.circuitBreaker("defaultCircuitBreaker", config);
    }

    /**
     * 创建外部服务调用断路器配置
     */
    @Bean
    public CircuitBreaker externalServiceCircuitBreaker(CircuitBreakerRegistry registry) {
        io.github.resilience4j.circuitbreaker.CircuitBreakerConfig config = io.github.resilience4j.circuitbreaker.CircuitBreakerConfig.custom()
                .failureRateThreshold(30)  // 外部服务失败率阈值更低，30%触发断路
                .slowCallRateThreshold(30) // 外部服务慢调用率阈值，30%触发断路
                .slowCallDurationThreshold(Duration.ofSeconds(2)) // 慢调用判定阈值
                .permittedNumberOfCallsInHalfOpenState(5) // 半开状态允许的调用次数
                .slidingWindowSize(50) // 滑动窗口大小
                .minimumNumberOfCalls(5) // 最小调用次数
                .waitDurationInOpenState(Duration.ofSeconds(30)) // 断路器打开状态持续时间
                .build();
        
        return registry.circuitBreaker("externalServiceCircuitBreaker", config);
    }
} 